use capnp_gen::deserialize_point;
use compio::io::{AsyncRead, AsyncWriteExt};
use compio::net::{TcpListener, TcpStream};
use compio::runtime::spawn;

#[allow(dead_code)]
async fn capnp_client(data: &[u8]) -> Result<(), Box<dyn std::error::Error>> {
    println!("started in CLIENT mode");

    let mut stream = TcpStream::connect("127.0.0.1:3000").await?;
    let _ = stream.write_all(data.to_vec()).await;

    Ok(())
}

#[allow(dead_code)]
async fn capnp_server(port: u16) -> Result<(), Box<dyn std::error::Error>> {
    println!("started in SERVER mode");
    let listener = TcpListener::bind(format!("127.0.0.1:{}", port)).await?;

    println!("server running at 127.0.0.1:{}", port);

    loop {
        match listener.accept().await {
            Ok((mut socket, addr)) => {
                spawn(async move {
                    println!("accepted connection from: {}", addr);
                    let buf = [0; 1024];
                    let mut sum = 0;
                    let mut full_msg: Vec<u8> = Vec::new();

                    loop {
                        let resp = socket.read(buf).await;
                        let n = match (resp.0, resp.1) {
                            (Ok(n), io_buf) => {
                                if n == 0 {
                                    println!(
                                        "read {:?} bytes, msg size: {:?}",
                                        sum,
                                        full_msg.len()
                                    );
                                    deserialize_point(&full_msg);
                                    return;
                                } else {
                                    full_msg.extend(io_buf[0..n].iter());
                                    n
                                }
                            }
                            (Err(e), _) => {
                                println!("error reading from socket: {}", e);
                                return;
                            }
                        };
                        sum += n;
                    }
                })
                .detach();
            }
            Err(e) => println!("error on client connection: {}", e),
        }
    }
}
